#ifndef GAME_HPP
#define GAME_HPP

#include "Tools.hpp"
#include "Utils.hpp"
#include "Snake.hpp"
#include "GameMap.hpp"
#include "Constant.hpp"

#include <chrono>
#include <conio.h>
#include <windows.h>

using namespace std;

/**
 * @class GameState
 * @brief 游戏自动机状态，用于模拟游戏进行的自动机状态并且保存一些附加的状态参数
 **/
struct GameState{
    /**
     * @brief 游戏大状态
     **/
    enum class ControlState{
        NULLSTATE = 0,
        MAINMENU = 1,
        INGAME = 2,
        SCOREBOARD = 3
    } controlState; ///< 当前自动机状态
    enum InGameState{
        NULLSTATE = 0,
        GAMEINIT = 1,
        GAMERUN = 2,
        GAMEEND = 3
    };
    enum NULLState{
        UNKNOWN = 0,
        INITIALIZING = 1,
        EXITING_NORMAL = 2,
        EXITING_ABNORMAL = 3
    };
    enum MENUState{

    };
    int stateValue; ///< 当前状态值（子状态）
};

/**
 * @class Game
 * @brief 游戏单例
 **/
class Game final {
public:
    void initialize(); ///< 初始化
    void update(); ///< 更新（延迟后绘图前）
    void lateUpdate(); ///< 更新（绘图后延迟前）
    
    void init_map(); ///< 初始化地图，生成蛇等
    void generate_map(); ///< 在旧地图基础上生成新地图

    void move_snake(); ///< 移动蛇
    void update_snake(); ///< 更新蛇的状态
    void late_update_snake(); ///< 后更新

    void draw(); ///< 绘制
    void end(); ///< 结束游戏，清理资源
    void set_loop(); ///< 更新帧状态
    inline void delay_fps(int); ///< 稳定帧率

    static Game &Singleton(); ///< 获取单例

private:
    MAP &mmap = MAP::Singleton(); ///< 游戏地图单例
    vector<shared_ptr<Snake>> _snakes; ///< 玩家
    GameState current_state, next_state; ///< 游戏运行状态机
    int frameCount; ///< 游戏帧率计数
    decltype(chrono::steady_clock::now()) lastCallTime; ///< 上一帧时间
    DrawEffects drawEffects;
};

// 绘制屏幕
void paintScreen(DrawEffects, const Map&);

#endif